import { _decorator, Component, Node, input, Input, EventTouch, Vec3, UITransform, view, Size, Prefab, instantiate, director, RigidBody2D, Collider2D, Contact2DType, Animation, v2, v3, find, AudioClip, Director } from 'cc';
import { AudioMgr } from './AudioMgr';
import { BoomMgr } from './BoomMgr';
import { BuffControl } from './BuffControl';
import { bullet } from './bullet';
import { GameConfig } from './config/GameConfig';
import { enemy } from './enemy';
import { GameOver } from './GameOver';
import { LifeMgr } from './LifeMgr';
import { scoreMgr } from './scoreMgr';
const { ccclass, property } = _decorator;

@ccclass('heroManager')
export class heroManager extends Component {


    // 子弹生成速度  每 n s生成一颗
    bulletRate: number = 0.2 // 0.3

    // 英雄生命值
    heroLife: number = 2;
    heroLifeDef: number = 2;

    // 当前节点的大小
    nodeUI: UITransform;
    // 页面大小
    viewSize: Size;


    // 子弹预制体
    @property(Prefab)
    bullet: Prefab;
    // 子弹2
    @property(Prefab)
    bullet2: Prefab;

    // 子弹类型 0 普通 1 蓝色子弹
    bulletType: number = 0;

    @property(AudioClip)
    dieAudio: AudioClip;

    // 生命数量管理器
    lifeMgr: LifeMgr;

    // 分数管理器
    myScoreMag: scoreMgr;


    // 子弹位置
    bullets:Node;

    start() {

        this.nodeUI = this.getComponent(UITransform)
        this.viewSize = view.getVisibleSize()

        this.bullets = find('Canvas/bullets')

        this.fly()

        this.shotBullet()

        this.lifeMgr = find('Canvas/syscontrol/life/lifeAmount').getComponent(LifeMgr)
        this.lifeMgr.setLifeAmount(this.heroLife)


        this.myScoreMag = find('Canvas/syscontrol/score/score_label/score_value').getComponent(scoreMgr)

        // 注册碰撞事件
        this.getComponent(Collider2D).on(Contact2DType.BEGIN_CONTACT, this.beginContact)

    }

    update(deltaTime: number) {

    }


    /**
     * 发射子弹
     */
    shotBullet() {
        this.schedule(() => this.shotOneBullet(), this.bulletRate)
    }
    
    shotOneBullet() {
        if(this.bulletType) {
            this.shotBullet2()
        }else {
            this.shotBullet1()
        }
    }

    /**
     * 切换子弹
     */
    switchBullet(type:number = 0) {
        this.bulletType = type
    }
    // 切换为普通子弹
    switch2Bullet0() {
        this.bulletType = 0
    }
    // 限时切换为超级子弹
    switchBulletLimit(type:number=1) {
        
        // 如果当前已经是超级子弹, 那么先取消这个延迟任务
        if(this.bulletType) {
            this.unschedule(this.switch2Bullet0)
        }
        
        // 立刻切换子弹
        this.switchBullet(type)
        // 超级子弹生效
        this.scheduleOnce(this.switch2Bullet0, GameConfig.bulletSuperTime)
    }

    /**
     * 发射子弹
     */
    shotBullet1() {
        let bulletNode = instantiate(this.bullet)
                
        // 子弹要放到外层
        bulletNode.setParent(this.bullets)
        
        // 在hero上方生成子弹
        let p = this.node.getPosition()
        p.y += this.node.getComponent(UITransform).height / 2 + 20
        bulletNode.setPosition(p)
    
    }
    shotBullet2() {
        // 准备两颗子弹
        let bulletNode1 = instantiate(this.bullet2)
        let bulletNode2 = instantiate(this.bullet2)
        // 速度更快
        bulletNode1.getComponent(bullet).speed = 8;
        bulletNode2.getComponent(bullet).speed = 8;

        // 子弹要放到外层
        bulletNode1.setParent(this.bullets)
        bulletNode2.setParent(this.bullets)
        
        // 在hero上方生成子弹
        let {x, y} = this.node.getPosition()
        y += this.node.getComponent(UITransform).height / 2 + 20

        bulletNode1.setPosition(v3(x - 15, y))
        bulletNode2.setPosition(v3(x + 15, y))

    }


    /**
     * 
     * 飞行
     * 
     */
    fly() {
        input.on(Input.EventType.TOUCH_MOVE, this.flyEvent, this)
    }

    // 飞行事件
    flyEvent(event: EventTouch) {

        // let { x, y } = event.getUILocation()

        // console.log('locaion:', event.getLocation())
        // console.log('uilocation:', event.getUILocation())
        // console.log('wordPosition:', this.node.getWorldPosition())

        // console.log('nodelocation:', this.node.getPosition())

        let delta = event.getUIDelta()

        let planePos = this.node.getWorldPosition()

        let {x, y} = planePos.add(new Vec3(delta.x, delta.y, 0))

        // hero 100 * 124, 令其不出边界
        let halfW = this.nodeUI.width / 2
        let halfH = this.nodeUI.height / 2
        // 左右不出边界
        if (x < halfW) {
            x = halfW
        } else if (x > this.viewSize.width - halfW) {
            x = this.viewSize.width - halfW
        }
        // 上下不出边界
        if (y < halfH) {
            y = halfH
        } else if (y > this.viewSize.height - halfH) {
            y = this.viewSize.height - halfH
        }

        this.node.setWorldPosition(new Vec3(x, y))
    }


    /**
     * 英雄死亡
     */
    heroDie() {
        if(this.heroLife > 0) {
            this.heroLife --
            this.lifeMgr.reduceLifeAmount()

            // 爆炸动画
            this.getComponent(Animation).play('hero_die')

            // 死亡音乐
            AudioMgr.inst.playOneShot(this.dieAudio);
            
            this.scheduleOnce(() => {
                
                this.getComponent(Animation).crossFade('hero', 0.6)
                
                // 回到原始位置
                // this.node.setPosition(v3(0, -360))

            }, 0.6)



            // 开局霸体




        }else{
            // game over
            this.gameOver()
        }
    }

    /**
     * 结束游戏:
     *  1. 移除hero
     *  2. 不在生成子弹
     *  3. 不在生成敌机(可以不做)
     *  4. 弹出game over
     */
    gameOver() {
        // 1.
        this.getComponent(Animation).play('hero_die')
        // 死亡音乐
        AudioMgr.inst.playOneShot(this.dieAudio);
        
        // 2.
        this.unscheduleAllCallbacks()
        
        // 4. 后续看如何全局共享变量
        // let score = find('Canvas/syscontrol/score/score_label/score_value').getComponent(scoreMgr).score
        // find('Canvas/syscontrol/gameover').getComponent(GameOver).showOver(score)

        find('Canvas/syscontrol/gameover').getComponent(GameOver).showOver(this.myScoreMag.score)

        
        
        // 1.
        this.scheduleOnce(() => {
            // this.node.destroy()
            // 不销毁此节点, 只是隐藏
            this.node.active = false
        }, 0.6)
    }


    /**
     * 
     * 重新开始游戏
     * 
     */
    restartGame() {
        
        this.node.getComponent(Animation).play()
        this.node.setPosition(v3(0, -360))
        this.node.active = true

        this.heroLife = this.heroLifeDef
        this.lifeMgr.setLifeAmount(this.heroLifeDef)

        this.myScoreMag.setScore(0)

        // 继续发射子弹
        this.shotBullet()
    }




    /**
     * 碰撞事件
     */
    beginContact(self: Collider2D, other: Collider2D) {

        /**
         * hero 0
         * bullet 1
         * enemy 2
         * 
         * bullet buf 3
         * boom buf 4
         * 
         */
        if(self.tag == 0 && other.tag == 2 ) {

            if(self.getComponent(heroManager).heroLife >= 0 && other.getComponent(enemy).hp > 0) {
                // 英雄死亡
                self.getComponent(heroManager).heroDie()
            }

        }else if (other.tag == 3) {
            
            self.getComponent(heroManager).switchBulletLimit(1)
            
            director.once(Director.EVENT_AFTER_PHYSICS, () => {
                // 销毁对象
                other.node.destroy()
            })

        }else if (other.tag == 4) {
            
            // 增加炸弹计数
            GameConfig.boomBuffAmount ++
            find('Canvas/syscontrol/bomb/boomAmount').getComponent(BoomMgr).setBoomAmount()
            
            
            director.once(Director.EVENT_AFTER_PHYSICS, () => {
                // 销毁对象
                other.node.destroy()
            })

        }
        



    }
}


